package com.sunrate.investingquote.client;

import com.sunrate.investingquote.enums.RetCode;
import com.sunrate.investingquote.exception.ServerException;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yyh
 * @description:
 * @date 2023/06/15/ 15:30
 */
@Slf4j
public class CustomerWebSocketClient extends WebSocketClient {

    public static final String ON_OPEN = "ON_OPEN";
    public static final String ON_MESSAGE = "ON_MESSAGE";
    public static final String ON_CLOSE = "ON_CLOSE";
    public static final String ON_ERROR = "ON_ERROR";

    private final Map<String, EventListener> eventListenerMap = new HashMap<>();


    public CustomerWebSocketClient(String serverUri) throws URISyntaxException {
        super(new URI(serverUri));
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        log.info("WebScoketClient open");
        getListener(ON_OPEN).done(serverHandshake);
    }

    @Override
    public void onMessage(String s) {
        log.info("WebScoketClient onMessage msg:{}", s);
        getListener(ON_MESSAGE).done(s);

    }

    @Override
    public void onClose(int i, String s, boolean b) {
        log.info("WebScoketClient onClose i:{},s:{},b:{}", i, s, b);
        getListener(ON_CLOSE).done(null);

    }

    @Override
    public void onError(Exception e) {
        log.error("WebScoketClient onError:", e);
        getListener(ON_ERROR).done(e);
    }

    private EventListener getListener(String eventType) {
        return eventListenerMap.getOrDefault(eventType, obj -> {
        });
    }

    public void addEventListener(String eventType, EventListener eventListener) {
        this.eventListenerMap.put(eventType, eventListener);
    }

    public void addOnOpenEventListener(EventListener eventListener) {
        this.eventListenerMap.put(ON_OPEN, eventListener);
    }

    public void addOnMessageEventListener(EventListener eventListener) {
        this.eventListenerMap.put(ON_MESSAGE, eventListener);
    }

    public void addOnCloseEventListener(EventListener eventListener) {
        this.eventListenerMap.put(ON_CLOSE, eventListener);
    }

    public void addOnErrorEventListener(EventListener eventListener) {
        this.eventListenerMap.put(ON_ERROR, eventListener);
    }


    @Override
    public void connect() {
        try {
            super.connect();
        } catch (Exception e) {
            log.error("WebScoketClient connect error", e);
            throw new ServerException(RetCode.CONNECT_CLIENT_ERROR);
        }
    }

    @FunctionalInterface
    public interface EventListener {

        void done(Object obj);
    }
}
